package com.my.shortestPath;

//Dijkstra算法
public class ShortestPath {

    //接受一个有向图的权重矩阵，和一个起点编号start（从0编号，顶点存在数组中)
    //返回一个int[] 数组，表示从start到它的最短路径长度
    public int[] dijsktra(int[][] weight, int start) {
        int length = weight.length;
        int[] shortPath = new int[length];//存放从start到各个点的最短距离
        shortPath[0] = 0;//start到他本身的距离最短为0
        String path[] = new String[length];//存放从start点到各点的最短路径的字符串表示
        for (int i = 0; i < length; i++) {
            path[i] = start + "->" + i;
        }
        boolean visited[] = new boolean[length];//标记当前该顶点的最短路径是否已经求出，1表示已经求出
        visited[0] = true;//start点的最短距离已经求出
        for (int count = 1; count < length; count++) {
            int k = -1;
            int dmin = Integer.MAX_VALUE;
            for (int i = 0; i < length; i++) {
                if (!visited[i] && weight[start][i] < dmin) {
                    dmin = weight[start][i];
                    k = i;
                }
            }
            //选出一个距离start最近的未标记的顶点     将新选出的顶点标记为以求出最短路径，且到start的最短路径为dmin。
            shortPath[k] = dmin;
            visited[k] = true;
            //以k为中间点，修正从start到未访问各点的距离
            for (int i = 0; i < length; i++) {
                if (!visited[i] && weight[start][k] + weight[k][i] < weight[start][i]) {
                    weight[start][i] = weight[start][k] + weight[k][i];
                    path[i] = path[k] + "->" + i;
                }
            }
        }
        for (int i = 0; i < length; i++) {
            System.out.println("从" + start + "出发到" + i + "的最短路径为：[" + path[i] + "], weight = " + shortPath[i]);
        }
        this.path = path;//保存最短路径结果
        return shortPath;

    }

    private String[] path;

    public String[] getPath() {
        if (path == null) {
            throw new IllegalArgumentException("dijsktra算法尚未运行");
        }
        return path;
    }
}
